﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace TSharp.Core.Aop.Handler
{
	/// <summary>
	/// 验证方法中参数不为null的处理类
	/// </summary>
	public class NotNullHandler : ICallHandler
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="NotNullHandler"/> class.
		/// </summary>
		/// <param name="parameterName">Name of the parameter.</param>
		/// <param name="order">The order.</param>
		public NotNullHandler(IList<string> parameterName, int order)
		{
			ParameterName = parameterName;
		}

		/// <summary>
		/// 不为空的参数名
		/// </summary>
		public IList<string> ParameterName { get; set; }

		#region ICallHandler Members

		/// <summary>
		/// Order in which the handler will be executed
		/// </summary>
		/// <value></value>
		public int Order { get; set; }

		/// <summary>
		/// Implement this method to execute your handler processing.
		/// </summary>
		/// <param name="input">Inputs to the current call to the target.</param>
		/// <param name="getNext">Delegate to execute to get the next delegate in the handler
		/// chain.</param>
		/// <returns>Return value from the target.</returns>
		public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
		{
			for (int i = 0; i < input.Inputs.Count; i++)
			{
				object target = input.Inputs[i];
				if (target == null)
				{
					ParameterInfo parameterInfo = input.Inputs.GetParameterInfo(i);
					if (ParameterName == null || ParameterName.Count == 0)
					{
						var ex = new ArgumentNullException(parameterInfo.Name);
						return input.CreateExceptionMethodReturn(ex);
					}
					else
					{
						foreach (string name in ParameterName)
						{
							if (parameterInfo.Name == name)
							{
								var ex = new ArgumentNullException(parameterInfo.Name);
								return input.CreateExceptionMethodReturn(ex);
							}
						}
					}
				}
			}
			return getNext()(input, getNext);
		}

		#endregion
	}
}